define(['jquery', 'domReady!', 'appLocalStorage', 'appConst',
        'model/global', 'model/testData', 'business/searchbar/searchbarBiz',
        'stringUtils', 'model/project', 'common/widgetUtils', 'common/mathUtils', 'model/export', 'appMessageBox', 'dateUtils', 'business/socket/socketBiz', 'd3/d3-main', 'x-editable/x-editable.min'],
    function ($, domReady, appLocalStorage, appConst, global, testDataM, searchbar, stringUtils, projectM, widgetUtils, mathUtils, chartExportM, msgBox, dateUtils, socketBiz) {
        var components = {};
        var data = {
            searchFields: {},
            testItemNameDS: [],
            currentTestItem: "",
            stationDS: [],
            slotDS: [],
            snDS: [],
            sedFilterValueDS: [],
            sedStationDS: [],
            sedSlotDS: [],
            sedSnDS: [],
            runChartWarningRuleDS: [],
            testData: [],
            currentSearchFields: {},
            currentTestDataPage: 1,
            testDataCheckAll: true,
            isFilterAllChanged: false,
            filterCache: {
                filterValue: "",
                includeId: "",
                excludeId: "",
                isCheckAll: null,
                hasExcludeId: false,
                changeValues: {}
            },
            chartName: {
                NDChart: "NDChart",
                RunChart: "RunChart",
                XBarChart: "XBarChart",
                SDChart: "SDChart",
                RChart: "RChart",
                MRChart: "MRChart"
            },
            currentTabName: "NDChart",
            custom: {
                defaultUsl: "",
                defaultLsl: "",
                usl: "",
                lsl: "",
                itemName: "",
                digit: 6,
                rcMaxSize: 1000,
                search_timeout_key_spc: "",
                soltkey: ""
            },
            importFiles: [],
            sedFilterType: {
                station: "station",
                slot: "slot",
                sn: "sn"
            },
            defineRLine: null,
            defineMRLine: null,
            ws: {
                sockjs: null,
                stomp: null
            }
        };
        var that;

        function getFileNameFromPath(filePath) {
            var path = filePath;
            var pos1 = path.lastIndexOf('/');
            var pos2 = path.lastIndexOf('\\');
            var pos = Math.max(pos1, pos2);
            var fileName = pos < 0 ? path : path.substring(pos + 1);
            return fileName;
        }

        return {
            init: function () {
                that = this;
                data.search_timeout_key_spc = appConst.searchKey.search_dataImport_timeout_key + global.getUserId();
                components = {
                    wgt_chart: $('#wgt_chart'),
                    wgt_items: $('#wgt_items'),
                    wgt_testData: $('#wgt_testData'),
                    tbl_items: $('#tbl_distinctTestItem'),
                    tbl_testData: $('#tbl_testData'),
                    drp_export: $('#drp_export'),
                    a_export_current: $('#a_export_current'),
                    txt_itemsFilter: $('#txt_itemsFilter'),
                    slt_sed_filterType: $('#slt_sed_filterType'),
                    slt_sed_filterValue: $('#slt_sed_filterValue'),
                    slt_sed_station: $('#slt_sed_station'),
                    slt_sed_slot: $('#slt_sed_slot'),
                    slt_sed_sn: $('#slt_sed_sn'),
                    btn_refreshChart: $('#btn_refreshChart'),
                    btn_export_all_submit: $('#btn_export_all_submit'),
                    btn_export_ndc_submit: $('#btn_export_ndc_submit'),
                    dlg_all_selectCharts: $('#dlg_all_selectCharts'),
                    dlg_ndc_selectItems: $('#dlg_ndc_selectItems'),
                    rda_checkedType: $('input[name=rda_checkedType]'),
                    ckb_all: $('#ckb_all'),
                    btn_testDataFilter: $('#btn_testDataFilter'),
                    txt_filterValue: $('#txt_filterValue'),
                    div_filterSearchBar: $('#div_filterSearchBar'),
                    btn_refreshCache: $('#btn_refreshCache'),
                    tab_chartTab: $('#tab_chartTab'),
                    div_NDChartLabel: $('#div_NDChartLabel'),
                    div_chartAlert: $('#div_chartAlert'),
                    div_chartAlertError: $('#div_chartAlertError'),
                    chart_ndc: $('#chart_NDC'),
                    chart_runc: $('#chart_RunC'),
                    chart_xbarc: $('#chart_XBarC'),
                    chart_sdc: $('#chart_SDC'),
                    chart_rc: $('#chart_RC'),
                    chart_mrc: $('#chart_MRC'),

                    wzd_spc_import: $('#wzd_spc_import'),
                    dlg_spc_import: $('#dlg_spc_import'),
                    slt_spc_import_project: $('#slt_spc_import_project'),
                    spn_spc_import_processbar: $('#spn_spc_import_processbar'),
                    spn_spc_import_logArea: $('#spn_spc_import_logArea'),
                    spn_spc_import_status: $('#spn_spc_import_status'),
                    btn_spc_import_submit: $('#btn_spc_import_submit'),
                    fle_spc_import_file: $('#fle_spc_import_file'),
                    btn_spc_import_gobackTo1: $('#btn_spc_import_gobackTo1'),
                    spn_spc_import_time: $('#spn_spc_import_time'),
                    alt_grr_import_msgbar: $('#alt_grr_import_msgbar'),
                    a_spc_import_showhistory: $('#a_spc_import_showhistory'),
                    fle_spc_import_bu5Name: $('#fle_spc_import_bu5Name'),
                    ckb_spc_import_enableBu5: $('#ckb_spc_import_enableBu5'),
                    div_spc_import_upload_files: $('#div_spc_import_upload_files'),
                    txt_spc_import_soltkey: $('#txt_spc_import_soltkey'),

                    modalNDC: {
                        slt_export_ndc_testItems: $('#slt_export_ndc_testItems'),
                        ckb_export_ndc_tb_topCheck: $('#ckb_export_ndc_tb_topCheck'),
                        alt_export_all: $('#alt_export_all'),
                        i_export_ndc_caret: $('#i_export_ndc_caret'),
                        tbl_export_ndc_testItem: $('#tbl_export_ndc_testItem'),
                        alt_export_ndc: $('#alt_export_ndc')
                    },
                    form_ispc_r_line: $("#form_ispc_r_line"),
                    txt_ispc_r_line1_name: $('#txt_ispc_r_line1_name'),
                    txt_ispc_r_line1_value: $("#txt_ispc_r_line1_value"),
                    txt_ispc_r_line2_name: $("#txt_ispc_r_line2_name"),
                    txt_ispc_r_line2_value: $("#txt_ispc_r_line2_value"),
                    btn_ispc_r_line_draw: $("#btn_ispc_r_line_draw"),

                    form_ispc_mr_line: $("#form_ispc_mr_line"),
                    txt_ispc_mr_line1_name: $("#txt_ispc_mr_line1_name"),
                    txt_ispc_mr_line1_value: $("#txt_ispc_mr_line1_value"),
                    txt_ispc_mr_line2_name: $("#txt_ispc_mr_line2_name"),
                    txt_ispc_mr_line2_value: $("#txt_ispc_mr_line2_value"),
                    btn_ispc_mr_line_draw: $("#btn_ispc_mr_line_draw")
                };
                that.initItemPanel();
                that.initChartPanel();
                that.initTestDataPanel();
                that.disableAllElementsDependOnItem();
                that.disableExportBtn();
                that.lineRDrawEvent();
            },
            searchEventListener: function (searchFields) {
                data.stationDS = searchbar.getStationDS();
                data.slotDS = searchbar.getSlotDS();
                data.searchFields = searchFields;
                that.resetChartPanel();
                that.cleanTestDataPanel();
                that.disableAllElementsDependOnItem();
                that.loadDistinctTestItems();
                that.loadRunChartWarningRulesDetails();

                that.activeExportBtn();
            },

            //Test item panel
            initItemPanel: function () {
                data.currentTestItem = "";
                that.initDistinctTestItemTable();
                that.initDistinctFilter();
            },
            initDistinctTestItemTable: function () {
                data.testItemNameDS = [];
                components.tbl_items.dataTable({
                    "sDom": "rt",
                    "processing": true,
                    "ordering": false,
                    "paging": false,
                    "lengthChange": false,
                    "searching": true,
                    "bFilter": false,
                    "data": function () {
                        return data.testItemNameDS;
                    },
                    "language": appConst.table_language(),
                    "columnDefs": [
                        {
                            "targets": [0],
                            "createdCell": function (td, cellData, rowData, row, col) {
                                $(td).attr('style', 'cursor:pointer;');
                            }
                        }
                    ]
                });

                components.tbl_items.find("thead").hide();

                components.tbl_items.find('tbody').on('click', 'tr', function () {
                    if ($(this).hasClass('active')) {
                        // $(this).removeClass('active');
                        return;
                    } else {
                        components.tbl_items.DataTable().$('tr.active').removeClass('active');
                        $(this).addClass('active');
                    }
                    data.currentTestItem = components.tbl_items.DataTable().row(this).data()[0];
                    data.custom.usl = "";
                    data.custom.lsl = "";
                    that.resetCharts();
                    that.loadDataPanel();
                });
            },
            initDistinctFilter: function () {
                components.txt_itemsFilter.on('keyup', function (e) {
                    var text = components.txt_itemsFilter.val();
                    that.doFilterDistinctTestItems(text);
                });
            },
            loadDistinctTestItems: function () {
                data.currentTestItem = "";
                components.txt_itemsFilter.val("");
                testDataM.findDistinctTestItem(data.searchFields, function (d) {
                    data.testItemNameDS = [];
                    $.each(d, function (i, obj) {
                        data.testItemNameDS.push([obj.value]);
                    });
                    components.tbl_items.dataTable().api().clear().column(0).search("");
                    components.tbl_items.dataTable().api().rows.add(data.testItemNameDS).draw();
                });
            },
            doFilterDistinctTestItems: function (param) {
                components.tbl_items.dataTable().api().column(0).search(param).draw();
            },

            //Chart panel methods.
            initChartPanel: function () {
                data.defineMRLine = {};
                data.defineRLine = {};

                that.initChartTab();
                that.initSedBarFilterType();
                that.initSedBarFilterValue();
                that.initChartPanelButtons();
                that.initExportModalDialog();

                that.initImportModalDialog();
            },
            initChartPanelButtons: function () {
                components.btn_refreshChart.on('click', function () {
                    var btn = $(this);
                    btn.trigger('mouseleave');
                    btn.button('loading');
                    data.custom.itemName = data.currentTestItem;
                    // that.resetDataPanel();
                    that.chartPanelAlertBar().hide();
                    that.resetCharts();
                    // that.pushCacheData(function () {
                    that.loadChart(data.currentTabName);
                    // });

                });
            },
            doExportChartsForOneItem: function () {
                var chartTypes = "";
                components.dlg_all_selectCharts.find("input[name='exportChartsType']:checked").each(function (i, e) {
                    chartTypes += $(this).val() + ",";
                });
                chartTypes = chartTypes.substring(0, chartTypes.length - 1);
                if (chartTypes == "") {
                    $('#alt_export_all').html($.i18n.prop('SPC_SINGLE_EXPORT_DIALOG_ALERT_NOSELECT')).fadeIn(200);
                    return;
                }

                var param = that.getSearchParamForTestData();
                param.search_chartTypes = chartTypes;
                param.search_projectName = data.searchFields.search_projectName;

                if (data.defineRLine != null) {
                    var rLine1Name = data.defineRLine.line1Name;
                    var rLine1Value = data.defineRLine.line1Value;
                    var rLine2Name = data.defineRLine.line2Name;
                    var rLine2Value = data.defineRLine.line2Value;
                    if (isNaN(rLine1Value)) {
                        rLine1Value = "";
                    }
                    if (isNaN(rLine2Value)) {
                        rLine2Value = "";
                    }
                    param.search_rLine1Name = rLine1Name;
                    param.search_rLine2Name = rLine2Name;
                    param.search_rLine1Value = rLine1Value;
                    param.search_rLine2Value = rLine2Value;
                }

                if (data.defineMRLine != null) {
                    var mrLine1Name = data.defineMRLine.line1Name;
                    var mrLine1Value = data.defineMRLine.line1Value;
                    var mrLine2Name = data.defineMRLine.line2Name;
                    var mrLine2Value = data.defineMRLine.line2Value;
                    if (isNaN(mrLine1Value)) {
                        mrLine1Value = "";
                    }
                    if (isNaN(mrLine2Value)) {
                        mrLine2Value = "";
                    }
                    param.search_mrLine1Name = mrLine1Name;
                    param.search_mrLine2Name = mrLine2Name;
                    param.search_mrLine1Value = mrLine1Value;
                    param.search_mrLine2Value = mrLine2Value;
                }

                chartExportM.exportChartsForOneItem(param, function (d) {
                    msgBox.show({
                        content: "<span id='grr_export_message' style='font-size:15px;'><i class='fa fa-refresh fa-spin animated'></i> Exporting ... You can track the exporting progress in <a href='#exportfile/all' > Export History</a></span>",
                        type: "success",
                        timeout: 0
                    });
                }, function () {

                });
            },
            doExportNDChartsForMoreItem: function (callback) {
                var items = components.modalNDC.slt_export_ndc_testItems.select2("val");
                if (stringUtils.isBlank(items)) {
                    components.modalNDC.alt_export_ndc.html($.i18n.prop('SPC_EXPORT_DIALOG_ALERT_NOSELECT')).show();
                    return;
                }
                var itemNames = "";
                for (var i = 0; i < items.length; i++) {
                    itemNames += items[i] + ",";
                }
                itemNames = itemNames.substring(0, itemNames.length - 1);
                var param = that.getSearchParamForTestData();
                param.search_projectName = data.searchFields.search_projectName;
                param.search_itemNames = itemNames;

                chartExportM.exportNDCForMoreItems(param, function (d) {
                    msgBox.show({
                        content: "<span id='grr_export_message' style='font-size:15px;'><i class='fa fa-refresh fa-spin animated'></i> Exporting ... You can track the exporting progress in <a href='#exportfile/all' > Export History</a></span>",
                        type: "success",
                        timeout: 0
                    });
                    if (typeof callback == "function") {
                        callback();
                    }
                }, function () {
                    if (typeof callback == "function") {
                        callback();
                    }
                });
            },
            initExportModalDialog: function () {
                that.initModalNDC();
                components.btn_export_all_submit.on('click', function () {
                    components.dlg_all_selectCharts.modal('hide');
                    // that.pushCacheData(function () {
                    that.doExportChartsForOneItem();
                    // });

                });
            },
            initModalNDC: function () {
                components.dlg_ndc_selectItems.on('show.bs.modal', function (e) {
                    var tb = components.modalNDC.tbl_export_ndc_testItem;
                    var tb_body = tb.find('tbody');
                    tb_body.empty();
                    components.modalNDC.alt_export_ndc.hide();
                    var ds = new Array();

                    for (var i = 0; i < data.testItemNameDS.length; i++) {
                        var tbContent = "<tr>"
                            + "<td><label class='checkbox'><input type='checkbox' name='checkbox-inline' value='" + data.testItemNameDS[i][0] + "'><i></i></label></td>"
                            + "<td>" + data.testItemNameDS[i][0] + "</td>"
                            + "</tr>";
                        tb.find('tbody').append(tbContent);
                        ds.push({id: data.testItemNameDS[i][0], text: data.testItemNameDS[i][0]});
                    }
                    components.modalNDC.slt_export_ndc_testItems.select2({
                        data: ds,
                        tags: true
                    });
                    components.modalNDC.slt_export_ndc_testItems.unbind('change');
                    components.modalNDC.slt_export_ndc_testItems.on('change', function (e) {
                        var array = $(this).select2("val");
                        components.modalNDC.tbl_export_ndc_testItem.find('tbody input[type=checkbox]').each(function () {
                            var index = $.inArray($(this).val(), array);
                            if (index != -1) {
                                $(this).prop('checked', true);
                            } else {
                                $(this).prop('checked', false);
                            }
                        });
                    }).on('select2-selecting', function (e) {
                    });

                    tb.find('tbody input[type=checkbox]').click(function (e) {
                        var array = components.modalNDC.slt_export_ndc_testItems.select2("val");
                        var index = $.inArray($(this).val(), array);
                        if (index != -1) {
                            array.splice(index, 1);
                        } else {
                            array.push($(this).val());
                        }
                        components.modalNDC.slt_export_ndc_testItems.select2("val", array);
                    });
                    components.modalNDC.slt_export_ndc_testItems.select2("val", []);
                    components.modalNDC.ckb_export_ndc_tb_topCheck.prop('checked', false).removeClass('checked');
                    components.dlg_ndc_selectItems.find('tbody input[type=checkbox]').prop('checked', false);
                });

                components.modalNDC.ckb_export_ndc_tb_topCheck.click(function (e) {
                    var selected = false;
                    if ($(this).hasClass('checked')) {
                        selected = true;
                        $(this).removeClass('checked');
                    } else {
                        $(this).addClass('checked');
                    }

                    var items = [];
                    components.dlg_ndc_selectItems.find('tbody input[type=checkbox]').each(function () {
                        if (selected) {
                            $(this).prop('checked', false);
                        }
                        else {
                            $(this).prop('checked', true);
                            items.push($(this).val());
                        }
                    });

                    if (selected) {
                        components.modalNDC.slt_export_ndc_testItems.select2("val", []);
                    } else {
                        components.modalNDC.slt_export_ndc_testItems.select2("val", items);
                    }
                });

                components.modalNDC.i_export_ndc_caret.click('click', function () {
                    if ($(this).hasClass('fa-caret-left')) {
                        $(this).removeClass('fa-caret-left').addClass('fa-caret-down');
                        $(this).next().show();
                        $(this).next().next().hide();
                    } else {
                        $(this).removeClass('fa-caret-down').addClass('fa-caret-left');
                        $(this).next().hide();
                        $(this).next().next().show();
                    }
                });

                components.btn_export_ndc_submit.on('click', function () {
                    that.doExportNDChartsForMoreItem(function () {
                        components.dlg_ndc_selectItems.modal('hide');
                    });
                });
            },
            initSedBarFilterType: function () {
                components.slt_sed_filterType.select2({
                    id: function (rs) {
                        return rs.id;
                    },
                    allowClear: true,
                    data: function () {
                        return {
                            results: [{id: "station", text: "Station"},
                                {id: "slot", text: "Slot"},
                                {id: "sn", text: "Serials Number"}]
                        };
                    },
                    formatResult: function (d) {
                        var itemFmt = "<span>" + d.text == null ? '' : d.text + "</span>";
                        return itemFmt;
                    },
                    formatSelection: function (d) {
                        return d.text == null ? '' : d.text;
                    },
                    formatMatches: function () {
                    },
                    formatNoMatches: function () {
                        return $.i18n.prop("GLOBAL_SELECTOR_NORESULT");
                    },
                    escapeMarkup: function (m) {
                        return m;
                    }
                });
                components.slt_sed_filterType.on('change', function (e) {
                    components.slt_sed_filterValue.select2('val', '');
                    that.loadSedFilterValue($(this).val());
                });
            },
            initSedBarFilterValue: function () {
                components.slt_sed_filterValue.select2({
                    id: function (rs) {
                        return rs.id;
                    },
                    allowClear: true,
                    data: function () {
                        return {results: data.sedFilterValueDS};
                    },
                    formatResult: function (d) {
                        var itemFmt = "<span>" + d.id == null ? '' : d.id + "</span>";
                        return itemFmt;
                    },
                    formatSelection: function (d) {
                        return d.id == null ? '' : d.id;
                    },
                    matcher: function (term, text, opt) {
                        return text.toUpperCase().indexOf(term.toUpperCase()) >= 0;
                    },
                    formatMatches: function (d) {
                    },
                    formatNoMatches: function () {
                        return $.i18n.prop("GLOBAL_SELECTOR_NORESULT");
                    },
                    escapeMarkup: function (m) {
                        return m;
                    }
                });
                components.slt_sed_filterValue.on('change', function (e) {
                    that.cleanCacheInServerSide(function () {
                        that.resetTestDataFilter();
                        that.loadTestData();
                        that.chartPanelAlertBar({
                            type: 'warning',
                            content: '<strong><i class="fa fa-exclamation-circle"></i> Condition is change, </strong> rebuilding the chart to apply the new setting.'
                        }).show();
                    });
                });
            },
            loadSedFilterValue: function (id) {
                data.sedFilterValueDS = [];
                if (data.sedFilterType.station == id) {
                    var stationIds = data.searchFields.search_stationIds;

                    if (stationIds == null || stationIds.length == 0) {
                        data.sedFilterValueDS = data.stationDS;
                    } else {
                        $.each(data.stationDS, function (i, obj) {
                            if ($.inArray(obj.id, stationIds) != -1) {
                                data.sedFilterValueDS.push(obj);
                            }
                        });
                    }
                } else if (data.sedFilterType.slot == id) {
                    var stationIds = data.searchFields.search_stationIds;
                    var slotIds = data.searchFields.search_slotIds;

                    $.each(data.stationDS, function (i, s) {
                        if (stationIds == null || stationIds.length == 0) {
                            $.each(s.slotNos, function (i, slot) {
                                var fullSlotText = s.id + "-" + slot;
                                data.sedFilterValueDS.push({id: fullSlotText, text: fullSlotText});
                            });
                            return true;
                        }
                        if ($.inArray(s.id, stationIds) != -1) {
                            $.each(s.slotNos, function (i, slot) {
                                var fullSlotText = s.id + "-" + slot;
                                if (slotIds != null && slotIds.length > 0) {
                                    if ($.inArray(fullSlotText, slotIds) != -1) {
                                        data.sedFilterValueDS.push({id: fullSlotText, text: fullSlotText});
                                    }
                                }
                                else {
                                    data.sedFilterValueDS.push({id: fullSlotText, text: fullSlotText});
                                }

                            });
                        }
                    });
                } else if (data.sedFilterType.sn == id) {
                    var searchParam = that.getSearchParamForTestData();
                    projectM.searchDistinctSN(searchParam, function (d) {
                        snDS = new Array();
                        $.each(d, function (i, obj) {
                            data.sedFilterValueDS.push({"id": obj, "text": obj});
                        });
                    });
                }
            },
            loadSedBarSN: function () {
                data.sedSnDS = [];
                var searchParam = that.getSearchParamForTestData();

                projectM.searchDistinctSN(searchParam, function (d) {
                    snDS = new Array();
                    $.each(d, function (i, obj) {
                        data.sedSnDS.push({"id": obj, "text": obj});
                    });
                });
            },
            resetSedBar: function () {
                data.sedFilterValueDS = [];
                components.slt_sed_filterType.select2('val', '');
                components.slt_sed_filterValue.select2('val', '');
                that.chartPanelAlertBar().hide();
            },
            resetChartPanel: function () {
                that.resetCharts();
                that.chartPanelAlertBar().hide();
                that.resetSedBar();
            },
            loadDataPanel: function () {
                that.activeAllElementsDependOnItem();
                that.resetTestDataFilter();
                that.chartPanelAlertBar().hide();
                that.cleanCacheInServerSide(function () {
                    //load chart
                    that.loadChart(data.currentTabName);

                    //load test data
                    that.loadTestData();
                });

            },
            initChartTab: function () {
                components.tab_chartTab.on('shown.bs.tab', function (e) {
                    data.currentTabName = $(this).find('li.active > a').attr('id');
                    if (stringUtils.isBlank(data.currentTestItem)) {
                        return false;
                    }
                    that.loadChart();
                });
            },
            loadChart: function () {
                widgetUtils.toggleWidgetLoading(components.wgt_chart, 'loading');
                var chartName = data.currentTabName;
                if (chartName == data.chartName.NDChart) {
                    var param = that.getSearchParamForTestData();
                    if (stringUtils.isNotBlank(data.custom.usl)) {
                        param.search_usl = data.custom.usl;
                    }
                    if (stringUtils.isNotBlank(data.custom.lsl)) {
                        param.search_lsl = data.custom.lsl;
                    }
                    testDataM.analyseNDC(param, function (d) {
                        components.btn_refreshChart.button('reset');
                        that.buildNDChart(d);
                        widgetUtils.toggleWidgetLoading(components.wgt_chart, true);
                    }, function () {
                        that.chartPanelAlertBar({
                            type: 'danger',
                            content: '<strong><i class="fa fa-warning"></i></strong> ' + $.i18n.prop('EXCEPTION_SPC_CHART_BUILD_ERROR')
                        }).show().delay(3000).fadeOut(300);
                        components.btn_refreshChart.button('reset');
                        widgetUtils.toggleWidgetLoading(components.wgt_chart, true);
                    });
                } else if (chartName == data.chartName.RunChart) {
                    var param = that.getSearchParamForTestData();
                    testDataM.analyseRC('analysis/analyseRunChart', param, function (d) {
                        if (d == null) {
                            return;
                        }
                        if (d.data == "") {
                            that.chartPanelAlertBar({
                                type: 'danger',
                                content: '<strong><i class="fa fa-warning"></i></strong> ' + $.i18n.prop('EXCEPTION_SPC_CHART_BUILD_ERROR')
                            }).show().delay(3000).fadeOut(300);
                            components.btn_refreshChart.button('reset');
                            widgetUtils.toggleWidgetLoading(components.wgt_chart, true);
                            return;
                        }
                        var lineObj = data.defineRLine;
                        that.buildRChartWithCache(components.chart_runc, d, 'analysis/analyseRunChart', lineObj);
                        components.btn_refreshChart.button('reset');
                        widgetUtils.toggleWidgetLoading(components.wgt_chart, true);
                    }, function () {
                        that.chartPanelAlertBar({
                            type: 'danger',
                            content: '<strong><i class="fa fa-warning"></i></strong> ' + $.i18n.prop('EXCEPTION_SPC_CHART_BUILD_ERROR')
                        }).show().delay(3000).fadeOut(300);
                        components.btn_refreshChart.button('reset');
                        widgetUtils.toggleWidgetLoading(components.wgt_chart, true);
                    });
                } else if (chartName == data.chartName.XBarChart) {
                    var param = that.getSearchParamForTestData();
                    testDataM.analyseRC('analysis/analyseXBarChart', param, function (d) {
                        if (d == null) {
                            return;
                        }
                        that.buildRChart(components.chart_xbarc, d);
                        components.btn_refreshChart.button('reset');
                        widgetUtils.toggleWidgetLoading(components.wgt_chart, true);
                    }, function () {
                        that.chartPanelAlertBar({
                            type: 'danger',
                            content: '<strong><i class="fa fa-warning"></i></strong> ' + $.i18n.prop('EXCEPTION_SPC_CHART_BUILD_ERROR')
                        }).show().delay(3000).fadeOut(300);
                        components.btn_refreshChart.button('reset');
                        widgetUtils.toggleWidgetLoading(components.wgt_chart, true);
                    });
                } else if (chartName == data.chartName.SDChart) {
                    var param = that.getSearchParamForTestData();
                    testDataM.analyseRC('analysis/analyseSDChart', param, function (d) {
                        if (d == null) {
                            return;
                        }
                        that.buildRChart(components.chart_sdc, d);
                        components.btn_refreshChart.button('reset');
                        widgetUtils.toggleWidgetLoading(components.wgt_chart, true);
                    }, function () {
                        that.chartPanelAlertBar({
                            type: 'danger',
                            content: '<strong><i class="fa fa-warning"></i></strong> ' + $.i18n.prop('EXCEPTION_SPC_CHART_BUILD_ERROR')
                        }).show().delay(3000).fadeOut(300);
                        components.btn_refreshChart.button('reset');
                        widgetUtils.toggleWidgetLoading(components.wgt_chart, true);
                    });
                } else if (chartName == data.chartName.RChart) {
                    var param = that.getSearchParamForTestData();
                    testDataM.analyseRC('analysis/analyseRChart', param, function (d) {
                        if (d == null) {
                            return;
                        }
                        that.buildRChart(components.chart_rc, d);
                        components.btn_refreshChart.button('reset');
                        widgetUtils.toggleWidgetLoading(components.wgt_chart, true);
                    }, function () {
                        that.chartPanelAlertBar({
                            type: 'danger',
                            content: '<strong><i class="fa fa-warning"></i></strong> ' + $.i18n.prop('EXCEPTION_SPC_CHART_BUILD_ERROR')
                        }).show().delay(3000).fadeOut(300);
                        components.btn_refreshChart.button('reset');
                        widgetUtils.toggleWidgetLoading(components.wgt_chart, true);
                    });
                } else if (chartName == data.chartName.MRChart) {
                    var param = that.getSearchParamForTestData();
                    testDataM.analyseRC('analysis/analyseMRChart', param, function (d) {
                        if (d == null) {
                            return;
                        }
                        var lineObj = data.defineMRLine;
                        that.buildRChart(components.chart_mrc, d, lineObj);
                        components.btn_refreshChart.button('reset');
                        widgetUtils.toggleWidgetLoading(components.wgt_chart, true);
                    }, function () {
                        that.chartPanelAlertBar({
                            type: 'danger',
                            content: '<strong><i class="fa fa-warning"></i></strong> ' + $.i18n.prop('EXCEPTION_SPC_CHART_BUILD_ERROR')
                        }).show().delay(3000).fadeOut(300);
                        components.btn_refreshChart.button('reset');
                        widgetUtils.toggleWidgetLoading(components.wgt_chart, true);
                    });
                }
            },
            buildNDChart: function (d) {
                that.fillNDChartLabel(d);
                components.chart_ndc.empty();
                var chartObj = d3.select('#chart_NDC');
                var barDataArray = d3.zip(d.histogramDataObj.divideValueAry, d.histogramDataObj.pointCountAry);

                var lcl = d.ndsDataItem.lclValue;
                var ucl = d.ndsDataItem.uclValue;
                var lsl = d.staDataItem.lslValue;
                var usl = d.staDataItem.uslValue;
                var stdValue = d.ndsDataItem.stdValue;
                var avgValue = d.ndsDataItem.avgValue;
                var ucl2lcl = ucl - lcl;
                var barX = d.histogramDataObj.divideValueAry;

                var lineset = new Array();
                lineset.push({data: lcl, color: fillcolor.red, name: 'LCL'});
                lineset.push({data: ucl, color: fillcolor.red, name: 'UCL'});
                lineset.push({data: avgValue, color: fillcolor.degreen, name: 'C'});
                lineset.push({data: avgValue - stdValue, color: fillcolor.green, name: '-σ'});
                lineset.push({data: avgValue + stdValue, color: fillcolor.green, name: 'σ'});
                lineset.push({data: avgValue - 2 * stdValue, color: fillcolor.green, name: '-2σ'});
                lineset.push({data: avgValue + 2 * stdValue, color: fillcolor.green, name: '2σ'});

                var cellOffset = 0;
                for (var i = 0, n = barDataArray.length, bin; i < n; i++) {
                    bin = barDataArray[i];
                    if (i == 0) {
                        bin.offset = 0;
                    }
                    else {
                        bin.offset = barDataArray[i - 1][0];
                    }
                    bin.width = bin[0] - bin.offset;
                    cellOffset = bin.width;
                    bin.height = bin[1];
                }
                barDataArray.shift();

                var slArray = new Array();
                slArray.push(lcl);
                slArray.push(ucl);

                if (usl != null) {
                    if (data.custom.defaultUsl != usl) {
                        slArray.push(usl);
                        lineset.push({data: usl, color: fillcolor.degreen, name: 'USL'});
                    } else {
                        if (usl <= (ucl + ucl2lcl)) {
                            slArray.push(usl);
                            lineset.push({data: usl, color: fillcolor.degreen, name: 'USL'});
                        }
                    }

                }
                if (lsl != null) {
                    if (data.custom.defaultLsl != lsl) {
                        slArray.push(lsl);
                        lineset.push({data: lsl, color: fillcolor.degreen, name: 'LSL'});
                    } else {
                        if (lsl >= (lcl - ucl2lcl)) {
                            slArray.push(lsl);
                            lineset.push({data: lsl, color: fillcolor.degreen, name: 'LSL'});
                        }
                    }

                }

                var allDataForX = d3.merge([d.histogramDataObj == null ? [] : d.histogramDataObj.divideValueAry,
                    slArray, d.curveDataObj == null ? [] : d.curveDataObj.xvalueAry]);
                allDataForX.push(d3.min(allDataForX) - cellOffset);
                allDataForX.push(d3.max(allDataForX) + cellOffset);

                var heightValue = 400;
                var margin = {top: 5, right: 30, bottom: 30, left: 70};
                var width = components.chart_ndc.width() - margin.left - margin.right;
                var height = heightValue - margin.top - margin.bottom;

                var xBarMax = d3.max(barX);
                var xBarMin = d3.min(barX);
                var xMax = d3.max(allDataForX);
                var xMin = d3.min(allDataForX);
                var yMax = d3.max(d.histogramDataObj.pointCountAry, function (d) {
                    return d;
                });

                var x = d3.scale.linear()
                    .domain([xMin, xMax])
                    .range([0, width]);

                var yUlimit = yMax + Math.ceil(yMax / 10);

                // var yUlimit = (5 - yMax % 5) + yMax;
                // var yTickValues = d3.range(0, yUlimit, yUlimit / 5);

                var y = d3.scale.linear()
                    .domain([0, yUlimit])
                    .range([height, 0]);

                var ry = d3.scale.linear()
                    .domain([0, d3.max(d.curveDataObj == null ? [] : d.curveDataObj.yvalueAry)])
                    .range([height, 15]);

                var xAxis = d3.svg.axis()
                    .scale(x)
                    .orient("bottom")
                    .tickSize(0, -height)
                    .tickPadding(8);

                // var yUlimit = (5 - yMax % 5) + yMax;
                // var ryTickValues = d3.range(0, 1, 1/yTickValues.length);

                var yAxis = d3.svg.axis()
                    .scale(y)
                    .orient("left")
                    .tickFormat(d3.format("C"))
                    .ticks(5)
                    .tickSize(-width, -width)
                    .tickPadding(8);

                var ryAxis = d3.svg.axis()
                    .scale(ry)
                    .orient("right")
                    .ticks(5)
                    .tickFormat(d3.format("C"))
                    .tickSize(0, 0)
                    .tickPadding(8);

                var barTip = d3.tip().attr('class', 'd3-tip')
                        .offset([-10, 0])
                        .html(function (d) {
                                return "<strong>Count:</strong> <span>" + d[1] + "</span><br/><span><strong>X:</strong> [" + mathUtils.round(d.offset, data.custom.digit) + " - " + mathUtils.round(d[0], data.custom.digit) + "]</span>";
                            }
                        )
                    ;

                var cycTip = d3.tip().attr('class', 'd3-tip')
                    .offset([-10, 0])
                    .html(function (d) {
                        return "<strong>" + d[0] + ",</strong> <span>" + d[1] + "</span>";
                    });

                chartObj.selectAll('g.bar').remove();

                var svg = chartObj
                    .append("svg")
                    .attr("width", width + margin.left + margin.right)
                    .attr("height", height + margin.top + margin.bottom);
                // .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

                var container = svg.append('g')
                    .attr("class", "focus")
                    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

                container.append("g")
                    .attr("class", "x axis")
                    .attr("transform", "translate(0," + height + ")")
                    .call(xAxis);

                container.append("g")
                    .attr("class", "y axis")
                    .call(yAxis);

                container.append("g")
                    .attr("class", "y axis")
                    .attr("transform", "translate(" + width + ",0)")
                    .call(ryAxis);

                drawChart(container);
                function drawChart(p) {
                    var barwidth = (x(xBarMax) - x(xBarMin)) / (barX.length - 1);
                    p.selectAll('.line').remove();
                    p.selectAll('text.linetext').remove();
                    p.selectAll('g.bars').remove();
                    p.selectAll('path.curveline').remove();

                    p.append('g')
                        .call(barTip)
                        .attr('class', 'bars')
                        .selectAll("rect")
                        .data(barDataArray)
                        .enter().append("rect")
                        .attr("class", "bar")
                        .attr("x", function (da, i) {
                            return x(da.offset);
                        })
                        .attr("width", function (da) {
                            return barwidth;
                        })
                        .attr("y", function (da) {
                            return y(da.height);
                        })
                        .attr("height", function (da) {
                            return height - y(da.height);
                        })
                        .attr('style', "fill:#3276B1;")
                        .on('mouseover', function (da, i) {
                            d3.select(this).style('fill', fillcolor.blue);
                            barTip.show(da);
                        })
                        .on('mouseout', function (da, i) {
                            d3.select(this).transition().duration(250).style('fill', '#3276B1');
                            barTip.hide();
                        });

                    p.selectAll('.line')
                        .data(lineset)
                        .enter().append("line")
                        .attr('class', 'line')
                        .attr('x1', function (da) {
                            return x(da.data);
                        })
                        .attr('x2', function (da) {
                            return x(da.data);
                        })
                        .attr('y1', function (da) {
                            return 12;
                        })
                        .attr('y2', function (da) {
                            return height;
                        })
                        .attr('stroke', function (da) {
                            return da.color;
                        })
                        .attr('stroke-width', '2')
                        .attr('style', 'clip-path: url(#clip);');

                    p.selectAll(".linetext")
                        .data(lineset)
                        .enter().append("text")
                        .text(function (d) {
                            return d.name;
                        })
                        .attr('class', 'linetext')
                        .attr("text-anchor", "middle")
                        .attr("x", function (da, i) {
                            return x(da.data);
                        })
                        .attr("y", function (da) {
                            return 10;
                        })
                        .attr("font-size", "11px")
                        .attr("fill", function (da) {
                            return da.color;
                        })
                        .attr('style', ' clip-path: url(#clip);');

                    var curveDataLine = d3.svg.line()
                        .x(function (da) {
                            return x(da[0]);
                        })
                        .y(function (da) {
                            return ry(da[1]);
                        });
                    // .interpolate('monotone');

                    var rPathData = d3.zip(d.curveDataObj == null ? [] : d.curveDataObj.xvalueAry, d.curveDataObj == null ? [] : d.curveDataObj.yvalueAry);

                    p.append("path")
                    // .datum(rPathData)
                        .attr("class", "curveline")
                        //.attr("style", "fill: none;stroke: brown;stroke-width: 1.5px;clip-path: url(#clip);")
                        .attr("style", "fill: none;stroke: brown;stroke-width: 1.5px;")
                        .attr("d", curveDataLine(rPathData));
                }
            },
            buildRChartWithCache: function (chart, d, url, lineObj) {
                var heightValue = 430;
                var rcMaxSize = data.custom.rcMaxSize;
                that.resetRunChartWarningRule(chart, d.ruleResultList);
                chart.empty();

                var margin = {top: 0, right: 30, bottom: 90, left: 60};
                var margin2 = {top: heightValue - 50, right: 30, bottom: 0, left: 60};

                var width = chart.width() - margin.left - margin.right;
                var height = heightValue - margin.top - margin.bottom;
                var height2 = heightValue - margin2.top - margin2.bottom;

                var svg = d3.select("#" + chart.attr('id'))
                    .append("svg")
                    .attr("width", width + margin.left + margin.right)
                    .attr("height", height + margin.top + margin.bottom);

                var container = svg.append('g')
                    .attr("class", "focus")
                    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

                var brusher = svg.append("g")
                    .attr("class", "context")
                    .attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");

                var brush_extent = [0, rcMaxSize];

                var totalNumber = d.data.length;
                var x2 = d3.scale.linear()
                    .domain([0, totalNumber])
                    .range([0, width]);

                var xAxis2 = d3.svg.axis()
                    .scale(x2)
                    .orient("bottom")
                    .tickFormat(d3.format("C"))
                    .tickPadding(8);

                var brush = d3.svg.brush()
                    .x(x2)
                    .on("brushend", brushed);

                if (brush_extent[1] < totalNumber) {
                    brush.extent(brush_extent);
                }

                brusher.append("g")
                    .attr("class", "x axis")
                    .attr("transform", "translate(0," + height2 + ")")
                    .call(xAxis2);

                brusher.append("g")
                    .attr("class", "x brush")
                    .call(brush)
                    .selectAll("rect")
                    .attr("y", -6)
                    .attr("height", height2 + 7);

                brusher.select('g.x.brush')
                    .selectAll('.extent');

                function brushed() {
                    var sd = brush.extent();
                    if (sd == null) {
                        sd = [0, rcMaxSize];
                    }
                    sd[0] = Math.floor(sd[0]);
                    sd[1] = Math.floor(sd[1]);

                    if ((sd[1] - sd[0]) > rcMaxSize) {
                        sd[1] = sd[0] + rcMaxSize;
                    } else if ((sd[1] - sd[0]) == 0) {
                        sd = [0, rcMaxSize];
                    } else if (sd[1] > totalNumber) {
                        sd[1] = totalNumber;
                    }

                    if (sd[1] <= totalNumber) {
                        d3.select(this).call(brush.extent(sd));
                    }

                    var search_param = that.getSearchParamForTestData();
                    $.extend(search_param, {"search_start": sd[0], "search_end": sd[1]});
                    testDataM.analyseRC(url, search_param, function (fd) {
                        drawCircle(container, fd, sd);
                    });
                }

                function drawCircle(p, dt, page) {
                    container.selectAll("g,path,line,text").remove();
                    brusher.selectAll("path,circle").remove();
                    var meanData = dt.meanData;
                    var meanLine = [
                        {value: meanData[0].toFixed(6), color: fillcolor.red, text: 'lcl'},
                        {value: meanData[1].toFixed(6), color: fillcolor.degreen, text: '-2σ'},
                        {value: meanData[2].toFixed(6), color: fillcolor.green, text: '-σ'},
                        {value: meanData[3].toFixed(6), color: 'black', text: 'u'},
                        {value: meanData[4].toFixed(6), color: fillcolor.green, text: 'σ'},
                        {value: meanData[5].toFixed(6), color: fillcolor.degreen, text: '2σ'},
                        {value: meanData[6].toFixed(6), color: fillcolor.red, text: 'ucl'}
                    ];

                    if (lineObj != null) {
                        if (!isNaN(lineObj.line1Value)) {
                            var line1 = {value: lineObj.line1Value.toFixed(6), color: fillcolor.blue, text: lineObj.line1Name};
                            meanData.push(lineObj.line1Value);
                            meanLine.push(line1);
                        }
                        if (!isNaN(lineObj.line2Value)) {
                            var line2 = {value: lineObj.line2Value.toFixed(6), color: fillcolor.blue, text: lineObj.line2Name};
                            meanData.push(lineObj.line2Value);
                            meanLine.push(line2);
                        }
                    }

                    var datasety = dt.data;
                    var datasetx = dt.timeStop;

                    if (datasetx == null || datasetx == "" || datasetx == undefined) {
                        datasetx = d3.range(1, datasety.length + 1, 1);
                    }

                    var realData = d3.zip(datasetx, datasety);
                    var lengthDatax = datasetx.length;

                    var offset = (meanData[meanData.length - 1] - meanData[0]) / (meanData.length - 1);
                    var offsetDatax = (datasetx[lengthDatax - 1] - datasetx[0]) / lengthDatax;
                    if (offset < 0) {
                        offset = -offset;
                    }
                    if (offsetDatax < 0) {
                        offsetDatax = -offsetDatax;
                    }
                    var yMax = Math.max(d3.max(meanData), d3.max(datasety)) + offset;
                    var yMin = Math.min(d3.min(meanData), d3.min(datasety)) - offset;

                    var xMax = Math.max(d3.max(datasetx)) + offsetDatax;
                    var xMin = Math.min(d3.min(datasetx)) - offsetDatax;

                    var scale = d3.scale.linear();
                    var x = scale
                        .domain([xMin, xMax + 1])
                        .range([0, width]);

                    var y = d3.scale.linear()
                        .domain([yMin, yMax])
                        .range([height, 10]);

                    var xlength = datasety.length + 1;
                    // var xa = d3.range(datasety.length + 1);
                    // if (xlength > 100) {
                    //     xa = d3.range(0, xlength, Math.round(xlength / 20));
                    // }

                    var xAxis = d3.svg.axis()
                        .scale(x)
                        .orient("bottom")
                        //.tickValues(xa)
                        .tickFormat(d3.format("C"))
                        .tickPadding(8)
                        .tickSize(-height + 10);

                    var yAxis = d3.svg.axis()
                        .scale(y)
                        .orient("left")
                        .tickFormat(d3.format(".2f"))
                        .tickSize(0)
                        .outerTickSize(-width)
                        .tickPadding(8);

                    container.append("g")
                        .attr("class", "x axis")
                        // .attr("style", "font: 10px sans-serif;color: #555;")
                        .attr("transform", "translate(0," + height + ")")
                        .call(xAxis);

                    container.append("g")
                        .attr("class", "y axis")
                        .attr("style", "font: 10px sans-serif;color: #555;")
                        .call(yAxis);

                    var line = container.selectAll('.line')
                        .data(meanLine)
                        .enter().append("line")
                        .attr('class', 'line')
                        .attr('x1', function (d) {
                            return 0;
                        })
                        .attr('x2', function (d) {
                            return width;
                        })
                        .attr('y1', function (d) {
                            return y(d.value);
                        })
                        .attr('y2', function (d) {
                            return y(d.value);
                        })
                        .attr('stroke', function (d) {
                            return d.color;
                        })
                        .attr('stroke-width', '1')
                        .attr("stroke-dasharray", function (d) {
                            return "3";
                        })
                        .style("opacity", "1");

                    var linetext = container.selectAll('.linetext')
                        .data(meanLine)
                        .enter().append('text')
                        .attr('class', 'linetext')
                        .text(function (cd) {
                            return cd.text + "=" + cd.value;
                        })
                        .attr("text-anchor", "middle")
                        .attr("x", function (cd, i) {
                            return width / 2;
                        })
                        .attr("y", function (cd) {
                            return y(cd.value) - 3;
                        })
                        .attr("font-size", "12px")
                        .attr("fill", function (cd) {
                            return cd.color;
                        })
                        .style("opacity", "1");

                    var tip = d3.tip().attr('class', 'd3-tip')
                        .offset([-10, 0])
                        .html(function (cd, i) {
                            return "<span>" + cd[1] + "</span>";
                        });

                    p.selectAll('g.bcg').remove();
                    p.selectAll('path.curveline').remove();

                    p.append("path")
                        .datum(realData)
                        .attr("class", "curveline")
                        .attr("d", d3.svg.line()
                            .x(function (cd, i) {
                                return x(cd[0]);
                            })
                            .y(function (cd) {
                                return y(cd[1]);
                            }));

                    var circles = p.append('g').call(tip).attr('class', 'bcg');
                    circles
                        .selectAll('.bcircle')
                        .data(realData)
                        .enter().append("circle")
                        .attr("class", 'bcircle')
                        .attr("fill", fillcolor.red)
                        .attr("r", 1.5)
                        .attr("cx", function (cd, i) {
                            return x(cd[0]);
                        })
                        .attr("cy", function (cd) {
                            return y(cd[1]);
                        })
                        .on('mouseover', function (cd, i) {
                            d3.select(this).transition().duration(250).attr('r', 5);
                            tip.show(cd, i);
                        })
                        .on('mouseout', function (cd, i) {
                            d3.select(this).transition().duration(250).attr('r', 1.5);
                            tip.hide();
                        });
                }

                drawCircle(container, d, brush_extent);
            },
            buildRChart: function (chart, d, lineObj) {
                var heightValue = 430;
                var rcMaxSize = data.custom.rcMaxSize;
                that.resetRunChartWarningRule(chart, d.ruleResultList);
                chart.empty();
                var meanData = d.meanData;

                var meanLine = [
                    {value: meanData[0].toFixed(6), color: fillcolor.red, text: 'lcl'},
                    {value: meanData[1].toFixed(6), color: fillcolor.degreen, text: '-2σ'},
                    {value: meanData[2].toFixed(6), color: fillcolor.green, text: '-σ'},
                    {value: meanData[3].toFixed(6), color: 'black', text: 'u'},
                    {value: meanData[4].toFixed(6), color: fillcolor.green, text: 'σ'},
                    {value: meanData[5].toFixed(6), color: fillcolor.degreen, text: '2σ'},
                    {value: meanData[6].toFixed(6), color: fillcolor.red, text: 'ucl'}
                ];

                if (lineObj != null) {
                    if (!isNaN(lineObj.line1Value)) {
                        var line1 = {value: lineObj.line1Value.toFixed(6), color: fillcolor.blue, text: lineObj.line1Name};
                        meanData.push(lineObj.line1Value);
                        meanLine.push(line1);
                    }
                    if (!isNaN(lineObj.line2Value)) {
                        var line2 = {value: lineObj.line2Value.toFixed(6), color: fillcolor.blue, text: lineObj.line2Name};
                        meanData.push(lineObj.line2Value);
                        meanLine.push(line2);
                    }
                }

                var datasety = d.data;
                var datasetx = d.timeStop;

                if (datasetx == null || datasetx == "" || datasetx == undefined) {
                    datasetx = d3.range(1, datasety.length + 1, 1);
                }
                var realData = d3.zip(datasetx, datasety);

                var lengthDatax = datasetx.length;

                var margin = {top: 0, right: 30, bottom: 90, left: 60};
                var margin2 = {top: heightValue - 50, right: 30, bottom: 0, left: 60};

                var width = chart.width() - margin.left - margin.right;
                var height = heightValue - margin.top - margin.bottom;
                var height2 = heightValue - margin2.top - margin2.bottom;

                var offset = (meanData[meanData.length - 1] - meanData[0]) / (meanData.length - 1);
                var offsetDatax = (datasetx[lengthDatax - 1] - datasetx[0]) / lengthDatax;

                if (offset < 0) {
                    offset = -offset;
                }
                if (offsetDatax < 0) {
                    offsetDatax = -offsetDatax;
                }
                var yMax = Math.max(d3.max(meanData), d3.max(datasety)) + offset;
                var yMin = Math.min(d3.min(meanData), d3.min(datasety)) - offset;
                //console.log(meanData);
                //console.log(d3.max(meanData));
                //console.log(d3.max(datasety));
                //console.log(yMax);
                var xMax = Math.max(d3.max(datasetx)) + offsetDatax;

                var xMin = Math.min(d3.min(datasetx)) - offsetDatax;

                var scale = d3.scale.linear();
                var x = scale
                    .domain([xMin, xMax])
                    .range([0, width]);

                var y = d3.scale.linear()
                    .domain([yMin, yMax])
                    .range([height, 10]);

                var x2 = d3.scale.linear()
                    .domain([xMin, xMax])
                    .range([0, width]);

                var y2 = d3.scale.linear()
                    .domain([yMin, yMax])
                    .range([height2, 10]);

                var xlength = datasety.length + 1;
                var xa = d3.range(datasety.length + 1);
                if (xlength > 100) {
                    xa = d3.range(0, xlength, Math.round(xlength / 20));
                }

                var xAxis = d3.svg.axis()
                    .scale(x)
                    .orient("bottom")
                    //.tickValues(xa)
                    .tickFormat(d3.format(".2f"))
                    .tickPadding(8)
                    .tickSize(-height + 10);

                var yAxis = d3.svg.axis()
                    .scale(y)
                    .orient("left")
                    .tickFormat(d3.format(".2f"))
                    .tickSize(0)
                    .outerTickSize(-width)
                    .tickPadding(8);

                var xAxis2 = d3.svg.axis()
                    .scale(x2)
                    .orient("bottom")
                    .tickFormat(d3.format("C"))
                    .tickPadding(8);

                var brush_extent = [0, xMax];
                var brush = d3.svg.brush()
                    .x(x2)
                    .on("brushend", brushed);

                if (datasety.length > rcMaxSize) {
                    brush_extent[1] = Math.round(datasety.length / 5);
                    brush.extent(brush_extent);
                }

                var svg = d3.select("#" + chart.attr('id'))
                    .append("svg")
                    .attr("width", width + margin.left + margin.right)
                    .attr("height", height + margin.top + margin.bottom)
                    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

                svg.append("defs").append("clipPath")
                    .attr("id", "clip")
                    .append("rect")
                    .attr("width", width)
                    .attr("height", height);

                var container = svg.append('g')
                    .attr("class", "focus")
                    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

                var brusher = svg.append("g")
                    .attr("class", "context")
                    .attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");


                function brushed() {
                    x.domain(brush.empty() ? x2.domain() : brush.extent());
                    drawCircle(container, realData);
                    container.select(".x.axis").call(xAxis);
                }

                container.append('g')
                    .attr('class', 'background')
                    .style('fill', 'white')
                    .append('rect')
                    .attr("width", width)
                    .attr("height", height);

                container.append("g")
                    .attr("class", "x axis")
                    .attr("transform", "translate(0," + height + ")")
                    .call(xAxis);

                container.append("g")
                    .attr("class", "y axis")
                    .call(yAxis);


                // brusher.append("g")
                //     .attr("class", "x axis")
                //     .attr("transform", "translate(0," + height2 + ")")
                //     .call(xAxis2);

                brusher.append("g")
                    .attr("class", "x brush")
                    .call(brush)
                    .selectAll("rect")
                    .attr("y", -6)
                    .attr("height", height2 + 7);

                var line = container.selectAll('.line')
                    .data(meanLine)
                    .enter().append("line")
                    .attr('class', 'line')
                    .attr('x1', function (d) {
                        return 0;
                    })
                    .attr('x2', function (d) {
                        return width;
                    })
                    .attr('y1', function (d) {
                        return y(d.value);
                    })
                    .attr('y2', function (d) {
                        return y(d.value);
                    })
                    .attr('stroke', function (d) {
                        return d.color;
                    })
                    .attr('stroke-width', '1')
                    .attr("stroke-dasharray", function (d) {
                        return "3";
                    })
                    .style("opacity", "1");

                var linetext = container.selectAll('.linetext')
                    .data(meanLine)
                    .enter().append('text')
                    .attr('class', 'linetext')
                    .text(function (d) {
                        return d.text + "=" + d.value;
                    })
                    .attr("text-anchor", "middle")
                    .attr("x", function (d, i) {
                        return width / 2;
                    })
                    .attr("y", function (d) {
                        return y(d.value) - 3;
                    })
                    .attr("font-size", "12px")
                    .attr("fill", function (d) {
                        return d.color;
                    })
                    .style("opacity", "1");
                brushed();
                function drawCircle(p, cd) {
                    var tip = d3.tip().attr('class', 'd3-tip')
                        .offset([-10, 0])
                        .html(function (dd, i) {
                            return "<span>" + dd[1] + "</span>";
                        });

                    p.selectAll('g.bcg').remove();
                    p.selectAll('path.curveline').remove();

                    p.append("path")
                        .datum(cd)
                        .attr("class", "curveline")
                        .attr("style", "fill: none;stroke: brown;stroke-width: 1px;")
                        .attr("d", d3.svg.line()
                            .x(function (dd, i) {
                                return x(dd[0]);
                            })
                            .y(function (dd) {
                                return y(dd[1]);
                            }));

                    var circles = p.append('g').call(tip).attr('class', 'bcg');
                    circles
                        .selectAll('.bcircle')
                        .data(cd)
                        .enter().append("circle")
                        .attr("class", 'bcircle')
                        .attr("fill", fillcolor.red)
                        .attr("r", 1.5)
                        .attr("cx", function (dd, i) {
                            return x(dd[0]);
                        })
                        .attr("cy", function (dd) {
                            return y(dd[1]);
                        })
                        .on('mouseover', function (dd, i) {
                            d3.select(this).transition().duration(250).attr('r', 5);
                            tip.show(dd, i);
                        })
                        .on('mouseout', function (dd, i) {
                            d3.select(this).transition().duration(250).attr('r', 1.5);
                            tip.hide();
                        });
                }
            },
            resetCharts: function () {
                that.resetNDChart();
                that.resetRChart();
            },
            resetNDChart: function () {
                that.cleanNDChartLabel();
                components.chart_ndc.empty();
            },
            resetRChart: function () {
                // that.cleanNDChartLabel();
                components.chart_runc.empty();
                components.chart_xbarc.empty();
                components.chart_rc.empty();
                components.chart_sdc.empty();
                components.chart_mrc.empty();
            },
            cleanNDChartLabel: function () {
                $('#spn_ndc_samples').empty().html('-');
                $('#spn_ndc_avg').empty().html('-');
                $('#spn_ndc_max').empty().html('-');
                $('#spn_ndc_min').empty().html('-');
                $('#spn_ndc_range').empty().html('-');
                $('#spn_ndc_stdev').empty().html('-');
                $('#spn_ndc_lcl').empty().html('-');
                $('#spn_ndc_ucl').empty().html('-');
                $('#spn_ndc_ku').empty().html('-');
                $('#spn_ndc_sk').empty().html('-');

                $('#spn_ndc_group').empty().html('-');
                $('#spn_ndc_usl').empty().editable('destroy');
                $('#spn_ndc_lsl').empty().editable('destroy');

                $('#spn_ndc_center').empty().html('-');

                $('#spn_ndc_ca').empty().html('-%').removeClass().addClass("pull-right label bg-color-lighten");
                $('#spn_ndc_cpk').empty().html('-').removeClass().addClass("pull-right label bg-color-lighten");
                $('#spn_ndc_cp').empty().html('-').removeClass().addClass("pull-right label bg-color-lighten");
                $('#spn_ndc_cpl').empty().html('-').removeClass().addClass("pull-right label bg-color-lighten");
                $('#spn_ndc_cpu').empty().html('-').removeClass().addClass("pull-right label bg-color-lighten");
            },
            fillNDChartLabel: function (d) {
                var ndsDataItem = {};
                var staDataItem = {};
                var pcDataItem = {};
                if (d != null) {
                    ndsDataItem = d.ndsDataItem;
                    staDataItem = d.staDataItem;
                    pcDataItem = d.pcDataItem;
                }
                $('#spn_ndc_samples').empty().html(ndsDataItem.dataCount != null ? ndsDataItem.dataCount : '-');
                $('#spn_ndc_avg').empty().html(ndsDataItem.avgValue != null ? mathUtils.round(ndsDataItem.avgValue, data.custom.digit) : '-');
                $('#spn_ndc_max').empty().html(ndsDataItem.maxValue != null ? mathUtils.round(ndsDataItem.maxValue, data.custom.digit) : '-');
                $('#spn_ndc_min').empty().html(ndsDataItem.minValue != null ? mathUtils.round(ndsDataItem.minValue, data.custom.digit) : '-');
                $('#spn_ndc_range').empty().html(ndsDataItem.rangeValue != null ? mathUtils.round(ndsDataItem.rangeValue, data.custom.digit) : '-');
                $('#spn_ndc_stdev').empty().html(ndsDataItem.stdValue != null ? mathUtils.round(ndsDataItem.stdValue, data.custom.digit) : '-');
                $('#spn_ndc_lcl').empty().html(ndsDataItem.lclValue != null ? mathUtils.round(ndsDataItem.lclValue, data.custom.digit) : '-');
                $('#spn_ndc_ucl').empty().html(ndsDataItem.uclValue != null ? mathUtils.round(ndsDataItem.uclValue, data.custom.digit) : '-');
                $('#spn_ndc_ku').empty().html(ndsDataItem.kurtosisValue != null ? mathUtils.round(ndsDataItem.kurtosisValue, data.custom.digit) : '-');
                $('#spn_ndc_sk').empty().html(ndsDataItem.skewnessValue != null ? mathUtils.round(ndsDataItem.skewnessValue, data.custom.digit) : '-');

                $('#spn_ndc_group').empty().html(staDataItem.groupValue != null ? staDataItem.groupValue : '-');
                var usl = staDataItem.uslValue != null ? mathUtils.round(staDataItem.uslValue, data.custom.digit) : '-';
                data.custom.defaultUsl = usl;
                if (stringUtils.isNotBlank(data.custom.usl)) {
                    usl = data.custom.usl;
                }
                var lsl = staDataItem.lslValue != null ? mathUtils.round(staDataItem.lslValue, data.custom.digit) : '-';
                data.custom.defaultLsl = lsl;
                if (stringUtils.isNotBlank(data.custom.lsl)) {
                    lsl = data.custom.lsl;
                }
                $('#spn_ndc_usl').editable({
                    value: usl,
                    validate: function (value) {
                        if (stringUtils.isBlank($.trim(value))) {
                            return 'This field is required';
                        }
                        if (!mathUtils.isNumeric($.trim(value))) {
                            return 'It must to be a number.';
                        }
                        if (mathUtils.str2Number($.trim(value)) <= mathUtils.str2Number($.trim($('#spn_ndc_lsl').html()))) {
                            return 'Please enter another one bigger than LSL.';
                        }
                        if (value != $(this).html()) {
                            that.chartPanelAlertBar({
                                type: 'warning',
                                content: '<strong><i class="fa fa-exclamation-circle"></i> Condition is change, </strong> rebuilding the chart to apply the new setting.'
                            }).show();
                        }
                    },
                    display: function (value) {
                        if (!value) {
                            return;
                        }
                        if (value != '-') {
                            data.custom.usl = value;
                        }
                        $(this).html(mathUtils.round(value, 6));
                    }
                });
                $('#spn_ndc_lsl').editable({
                    value: lsl,
                    validate: function (value) {
                        if (stringUtils.isBlank($.trim(value))) {
                            return 'This field is required';
                        }
                        if (!mathUtils.isNumeric($.trim(value))) {
                            return 'It must to be a number.';
                        }
                        if (mathUtils.str2Number($.trim(value)) >= mathUtils.str2Number($.trim($('#spn_ndc_usl').html()))) {
                            return 'Please enter another one smaller than USL.';
                        }
                        if (value != $(this).html()) {
                            that.chartPanelAlertBar({
                                type: 'warning',
                                content: '<strong><i class="fa fa-exclamation-circle"></i> Condition is change, </strong> rebuilding the chart to apply the new setting.'
                            }).show();
                        }
                    },
                    display: function (value) {
                        if (!value) {
                            return;
                        }
                        if (value != '-') {
                            data.custom.lsl = value;
                        }
                        $(this).html(mathUtils.round(value, 6));
                    }
                });

                $('#spn_ndc_center').empty().html(staDataItem.centerValue != null ? mathUtils.round(staDataItem.centerValue, data.custom.digit) : '-');

                $('#spn_ndc_ca').empty().html(that.checkNdcPcData($('#spn_ndc_ca'), pcDataItem.caData, 4) + "%");
                $('#spn_ndc_cpk').empty().html(that.checkNdcPcData($('#spn_ndc_cpk'), pcDataItem.cpkData, data.custom.digit));
                $('#spn_ndc_cp').empty().html(that.checkNdcPcData($('#spn_ndc_cp'), pcDataItem.cpData, data.custom.digit));
                $('#spn_ndc_cpl').empty().html(that.checkNdcPcData($('#spn_ndc_cpl'), pcDataItem.cplData, data.custom.digit));
                $('#spn_ndc_cpu').empty().html(that.checkNdcPcData($('#spn_ndc_cpu'), pcDataItem.cpuData, data.custom.digit));
            },
            checkNdcPcData: function (obj, d, digit) {
                obj.removeClass().addClass("pull-right label");
                if (d == null) {
                    obj.addClass('bg-color-lighten');
                    return '-'
                }
                var gtype = d.gType;
                if (gtype == null) {
                    obj.addClass('bg-color-lighten');
                }

                if (gtype == 'EXCELLENT') {
                    obj.addClass('bg-color-green');
                } else if (gtype == 'GOOD') {
                    obj.addClass('bg-color-blue');
                } else if (gtype == 'ACCEPTABLE') {
                    obj.addClass('bg-color-blueLight');
                } else if (gtype == 'ABOVE_RECTIFICATION') {
                    obj.addClass('bg-color-orange');
                } else if (gtype == 'RECTIFICATION') {
                    obj.addClass('bg-color-red');
                } else if (gtype == 'NORMAL') {
                    obj.addClass('bg-color-grayDark');
                }
                return mathUtils.round(d.value, digit);
            },

            loadRunChartWarningRulesDetails: function () {
                data.runChartWarningRuleDS = [];
                projectM.getRunChartWarningRule(data.searchFields.search_projectId, function (d) {
                    $.each(d, function (i, rule) {
                        var obj = {id: rule.id, code: rule.code, text: rule.detailRule};

                        if (stringUtils.isNotBlank(obj.text)) {
                            if (obj.text.indexOf("[n]") != -1) {
                                obj.text = obj.text.replace("[n]", rule.points);
                            }
                            if (obj.text.indexOf("[s]") != -1) {
                                obj.text = obj.text.replace("[s]", rule.sigma);
                            }
                            if (obj.text.indexOf("[m]") != -1) {
                                obj.text = obj.text.replace("[m]", rule.somePoints);
                            }
                        }
                        data.runChartWarningRuleDS.push(obj);
                    });
                });
            },
            resetRunChartWarningRule: function (chart, rules) {
                var labels = chart.parent().parent().prev('div');
                //clean rule labels
                labels.find('span.label').removeClass('bg-color-red', 'bg-color-green').addClass('bg-color-green');
                labels.find('span.label').each(function () {
                    $(this).html($(this).attr('data-code'));
                });
                // var rules = d;
                $.each(data.runChartWarningRuleDS, function (i, obj) {
                    var lb = labels.find('span.label[data-code=' + obj.code + ']');
                    var inArray = false;
                    $.each(rules, function (i, rule) {
                        if (rule.ruleName == obj.code) {
                            inArray = true;
                            if (rule.overRule == true) {
                                lb.removeClass().addClass("label bg-color-red");
                                if (rule.ruleName == "R1") {
                                    lb.html(obj.code + "-[" + rule.pos + "]");
                                }
                            }

                            return false;
                        }
                    });
                    lb.attr('data-original-title', obj.text);
                    if (inArray == false) {
                        lb.hide();
                    }
                });
            },
            chartPanelAlertBar: function (opt, d) {
                if (stringUtils.isBlank(data.currentTestItem)) {
                    return components.div_chartAlert;
                }
                var defaultp = {
                    type: "warning", //danger
                    opt: "show", //hide
                    content: ""
                };
                var options = $.extend({}, defaultp, opt);

                components.div_chartAlert.html('');

                if (options.type == "warning") {
                    components.div_chartAlert.removeClass("alert-warning alert-danger").addClass('alert-warning');
                } else if (options.type == "danger") {
                    components.div_chartAlert.removeClass("alert-warning alert-danger").addClass('alert-danger');
                }
                if (stringUtils.isNotBlank(options.content)) {
                    components.div_chartAlert.html(options.content);
                }

                return components.div_chartAlert;
            },

            //TestData panel
            initTestDataPanel: function () {
                components.btn_refreshCache.on('click', function (e) {
                    that.cleanCacheInServerSide(function () {
                        that.resetTestDataFilter();
                        that.loadTestData();
                    });
                });
                that.initTestDataTable();
                that.initTestDataFilter();
            },
            initTestDataFilter: function () {
                components.btn_testDataFilter.on('click', function (e) {
                    // that.pushCacheData(function () {
                    that.loadTestData(function () {
                        that.cleanFilterCache();
                    });
                    // });
                });

                components.rda_checkedType.on('change', function (e) {
                    var radio = $(this);
                    // that.pushCacheData(function () {
                    if (radio.val() == "UNCHECK") {
                        components.ckb_all.prop('checked', false);


                        that.loadTestData(function () {
                            that.cleanFilterCache();
                            data.filterCache.testDataCheckAll = false;
                        });
                    } else if (radio.val() == "CHECK") {
                        components.ckb_all.prop('checked', 'checked');
                        that.loadTestData(function () {
                            that.cleanFilterCache();
                            data.filterCache.testDataCheckAll = true;
                        });
                    } else if (radio.val() == "ALL") {
                        that.loadTestData(function () {
                            that.cleanFilterCache();
                            data.filterCache.testDataCheckAll = true;
                        });
                    }
                });
                // });
            },
            initTestDataTable: function () {
                data.testData = [];
                components.tbl_testData.dataTable({
                    "sDom": "t<'dt-toolbar-footer'<'col-sm-6 col-xs-12 hidden-xs'i><'col-xs-12 col-sm-6'p>>",
                    //"sDom": "<'row'<'col-sm-12' rt>> <'row'<'col-sm-6' i><'col-sm-6' p>>",
                    // "autoWidth": true,
                    "processing": true,
                    "ordering": false,
                    "paging": true,
                    "lengthChange": false,
                    "pageLength": global.getPageSize(),
                    // "pagingType": "input",
                    // "sPaginationType": "listbox",
                    // "sPaginationType": "ellipses",
                    "searching": true,
                    "serverSide": true,
                    "stateSave": false,
                    "language": appConst.table_language(),
                    "bFilter": false,
                    "ajax": {
                        "url": "empty",
                        "type": "POST",
                        "dataSrc": "body",
                        "traditional": true,
                        "data": that.getSearchParamForTestData,
                        "error": function (e) {
                            if (e.status == 401) {
                                msgBox.sessionFailureBox();
                            }
                            if (e.status == 500) {
                                msgBox.serverFailureBox();
                            }
                            if (e.status == 404) {
                                msgBox.pathFailureBox();
                            }
                            widgetUtils.toggleWidgetLoading(components.wgt_testData);
                        }
                    },
                    "columns": [
                        {"data": null},
                        {"data": null},
                        {"data": "id"},
                        {"data": "serialNumber"},
                        {"data": "upperLimit"},
                        {"data": "lowerLimit"},
                        {"data": "unitName"},
                        {"data": "testedValue"},
                        {"data": "isPass"}
                    ],
                    "columnDefs": [
                        {
                            "targets": [0],
                            "render": function (d, type, full) {
                                var result = "<label class='checkbox'><input type='checkbox' id=ckb_" + full.id + "  value=" + full.id + "><i></i></label>";
                                if (full.isCheck == true) {
                                    result = "<label class='checkbox'><input type='checkbox' id=ckb_" + full.id + "  value=" + full.id + " checked='checked'><i></i></label>";
                                }
                                data.filterCache.hasExcludeId = full.hasExcludeId;
                                return result;
                            },
                            "searchable": false,
                            "className": "smart-form"
                        },
                        {
                            "targets": [2],
                            "visible": false,
                            "searchable": false
                        },
                        {
                            "targets": [3],
                            "render": function (data, type, full) {
                                if (data == null) {
                                    return "";
                                }
                                return type === 'display' && data.length > 40 ?
                                '<span title="' + data + '">' + data.substr(0, 38) + '...</span>' :
                                    data;
                            }
                        },
                        {
                            "targets": [8],
                            "render": function (data, type, full) {
                                var result = '';
                                if (data == true) {
                                    result = '<span class="label label-success">' + $.i18n.prop("SPC_GRID_PASS") + '</span>';
                                } else if (data == false) {
                                    result = '<span class="label label-warning">' + $.i18n.prop("SPC_GRID_FAILED") + '</span>';
                                }
                                return result;
                            },
                            "searchable": false
                        }
                    ]
                });
                components.tbl_testData.DataTable().on('draw.dt', function () {
                    var dt = $(this).dataTable();
                    dt.api().column(1, {draw: 'applied'}).nodes().each(function (cell, i) {
                        var pageNum = dt.api().page();
                        var pageSize = dt.api().page.len();
                        cell.innerHTML = pageNum * pageSize + i + 1;
                    });
                    components.tbl_testData.find('tbody tr input[type=checkbox]').on('click', function (e) {
                        var checkbox = $(this);
                        that.pushSelectDataToCache(checkbox, function () {
                            that.checkTheSelectAllBox();
                        });
                    });
                    that.checkTheSelectAllBox();
                });

                components.ckb_all.on('click', function (e) {
                    data.filterCache.includeId = "";
                    data.filterCache.excludeId = "";
                    var checkbox = $(this);

                    if (checkbox.is(':checked')) {
                        data.filterCache.isCheckAll = true;
                    } else {
                        data.filterCache.isCheckAll = false;
                    }
                    data.filterCache.filterValue = components.txt_filterValue.val();
                    components.tbl_testData.find('tbody').find('input[type=checkbox]').prop('checked', data.filterCache.isCheckAll);
                    that.pushAllDataToCache();
                    that.pushCacheData();
                });

            },
            loadTestData: function (callback) {
                if (stringUtils.isBlank(data.currentTestItem)) {
                    return;
                }
                widgetUtils.toggleWidgetLoading(components.wgt_testData);
                components.tbl_testData.DataTable().ajax.url("analysis/testData").load(function () {
                    widgetUtils.toggleWidgetLoading(components.wgt_testData);
                    if (typeof callback == 'function') {
                        callback();
                    }
                });
            },
            hasExcludeItemInCurrentPage: function () {
                components.tbl_testData.Datatable().row()
                return false;
            },
            resetTestDataFilter: function () {
                components.rda_checkedType.each(function (i, obj) {
                    $(this).prop('checked', false);
                    if ($(this).val() == 'ALL') {
                        $(this).prop('checked', 'checked');
                    }
                });

                components.ckb_all.prop('checked', 'checked');
                components.txt_filterValue.val('');
                that.cleanFilterCache();
                data.filterCache.includeId = "";
                data.filterCache.excludeId = "";
            },
            cleanTestDataPanel: function () {
                that.resetTestDataFilter();
                that.cleanTestDataTable();
            },
            cleanTestDataTable: function () {
                widgetUtils.toggleWidgetLoading(components.wgt_testData);
                components.tbl_testData.DataTable().ajax.url("empty").load(function () {
                    widgetUtils.toggleWidgetLoading(components.wgt_testData);
                });
                // components.tbl_testData.DataTable().clear().draw();
            },
            cleanCacheInServerSide: function (callback) {
                var searchParam = {
                    "search_projectId": data.searchFields.search_projectId
                };
                testDataM.cleanTestDataCache(searchParam, function (d) {
                    if (typeof callback == 'function') {
                        callback();
                    }
                });
            },
            getSearchParamForTestData: function (paramters) {
                var sedFilterType = components.slt_sed_filterType.select2('val');
                var sedFilterValue = components.slt_sed_filterValue.select2('val');


                var searchParam = {
                    "search_stationIdOrSlotNo": data.searchFields.search_stationIdOrSlotNo,
                    "search_projectId": data.searchFields.search_projectId,
                    "search_serialNumber": data.searchFields.search_serialNumber,
                    "search_startTime": data.searchFields.search_startTime,
                    "search_stopTime": data.searchFields.search_stopTime,
                    "search_itemName": data.currentTestItem
                };
                if (stringUtils.isNotBlank(sedFilterValue)) {
                    if (data.sedFilterType.sn == sedFilterType) {
                        searchParam.search_serialNumber = sedFilterValue;
                    } else if (data.sedFilterType.station == sedFilterType) {
                        var stations = new Array();
                        var s = {'stationId': sedFilterValue, 'slotNos': []};

                        var slotIds = data.searchFields.search_slotIds;
                        if (slotIds != null && slotIds.length > 0) {
                            $.each(slotIds, function (i, slot) {
                                var ds = searchbar.getSplitDataFromSlot(slot);
                                if (ds.station == s.stationId) {
                                    s.slotNos.push(ds.slot);
                                }
                            });
                        }
                        stations.push(s);
                        searchParam.search_stationIdOrSlotNo = JSON.stringify(stations);
                    } else if (data.sedFilterType.slot == sedFilterType) {
                        var stations = new Array();
                        var ds = searchbar.getSplitDataFromSlot(sedFilterValue);

                        var s = {'stationId': ds.station, 'slotNos': []};
                        s.slotNos.push(ds.slot);
                        stations.push(s);
                        searchParam.search_stationIdOrSlotNo = JSON.stringify(stations);
                    }
                }

                // third searching bar - filters
                var filterValue = components.txt_filterValue.val();

                if (data.isFilterAllChanged == true) {
                    searchParam.search_filterCache = data.filterCache.changeValues;
                }

                searchParam.search_filterValue = filterValue;
                searchParam.search_checkType = that.getFilterCheckType();

                if (paramters != null) {
                    $.extend(paramters, searchParam);
                    paramters['draw'] = paramters.draw;
                    return paramters;
                } else {
                    return searchParam;
                }
            },
            cleanFilterCache: function () {
                data.isFilterAllChanged = false;
                data.filterCache.filterValue = "";
                data.filterCache.checkType = "ALL";
                data.filterCache.isCheckAll = null;
            },
            checkTheSelectAllBox: function () {
                var checkType = that.getFilterCheckType();
                if (checkType == 'ALL') {
                    if (data.filterCache.hasExcludeId == true) {
                        components.ckb_all.prop('checked', '');
                    } else {
                        components.ckb_all.prop('checked', 'checked');
                    }
                } else if (checkType == 'UNCHECK') {
                    var checked = true;
                    components.tbl_testData.find('tbody').find('input[type=checkbox]').each(function (i, obj) {
                        if (!$(this).is(':checked')) {
                            checked = false;
                            return false;
                        }
                    });
                    if (checked) {
                        components.ckb_all.prop('checked', 'checked');
                    } else {
                        components.ckb_all.prop('checked', '');
                    }
                } else if (checkType == 'CHECK') {
                    var checked = true;
                    components.tbl_testData.find('tbody').find('input[type=checkbox]').each(function (i, obj) {
                        if (!$(this).is(':checked')) {
                            checked = false;
                            return false;
                        }
                    });
                    if (checked) {
                        components.ckb_all.prop('checked', 'checked');
                    } else {
                        components.ckb_all.prop('checked', '');
                    }
                }
            },
            pushSelectDataToCache: function (checkbox, callback) {
                var id = checkbox.val();
                data.filterCache.includeId = "";
                data.filterCache.excludeId = "";
                if (checkbox.is(':checked')) {
                    data.filterCache.includeId = id;
                } else {
                    data.filterCache.excludeId = id;
                }
                that.pushCacheData(function () {
                    if ($.isFunction(callback)) {
                        callback();
                    }
                });
            },
            pushCacheData: function (callback) {
                var searchParam = that.getSearchParamForTestData();
                searchParam.search_includeId = data.filterCache.includeId;
                searchParam.search_excludeId = data.filterCache.excludeId;

                testDataM.saveTestDataCache(searchParam, function (d) {
                    data.filterCache.hasExcludeId = d;
                    data.filterCache.changeValues = "";

                    if ($.isFunction(callback)) {
                        callback();
                    }
                }, function () {
                    if ($.isFunction(callback)) {
                        callback();
                    }
                });

            },
            pushAllDataToCache: function (callback) {
                // var searchParam = that.getSearchParamForTestData();
                // searchParam.search_isAllCheck = data.filterCache.isCheckAll;
                data.isFilterAllChanged = true;

                // if (data.isFilterAllChanged == true) {
                data.filterCache.changeValues = JSON.stringify({
                    isChanged: true,
                    filterValue: data.filterCache.filterValue,
                    checkType: that.getFilterCheckType(),
                    isAllCheck: data.filterCache.isCheckAll.toString()
                });

                // data.filterCache = searchParam;
                // }

                // testDataM.saveTestDataCache(searchParam, function (d) {
                //     data.filterCache.hasExcludeId = d;
                //     if ($.isFunction(callback)) {
                //         callback();
                //     }
                // }, function () {
                //     if ($.isFunction(callback)) {
                //         callback();
                //     }
                // });
            },
            getFilterCheckType: function () {
                var checkType = "ALL";
                components.rda_checkedType.each(function (i, obj) {
                    if ($(this).is(':checked')) {
                        checkType = $(this).val();
                    }
                });
                return checkType;
            },

            //Import modal dialog
            initImportModalDialog: function () {

                var wizard = components.wzd_spc_import;
                wizard.wizard('selectedItem', {
                    step: 1
                });

                components.slt_spc_import_project.select2({
                    id: function (rs) {
                        return rs.id;
                    },
                    allowClear: true,
                    data: function () {
                        return {results: data.projectDS, text: 'name'};
                    },
                    formatResult: function (data) {
                        var itemFmt = "<span>" + data.name == null ? '' : data.name + "</span>";
                        return itemFmt;
                    },
                    formatSelection: function (data) {
                        return data.name == null ? '' : data.name;
                    },
                    formatMatches: function () {
                    },
                    formatNoMatches: function () {
                        return $.i18n.prop("GLOBAL_SELECTOR_NORESULT");
                    },
                    escapeMarkup: function (m) {
                        return m;
                    }
                });
                components.slt_spc_import_project.on('change', function (e) {

                });

                components.dlg_spc_import.on('show.bs.modal', function (e) {
                    that.cleanSocket();
                    that.initSocket();
                    // var soltkey = Math.floor(Math.random(10) * 1000000);
                    // components.txt_spc_import_soltkey.val(soltkey);
                    // var ws = socketBiz.initImport(soltkey, that.socketCallback);
                    // data.ws.sockjs = ws.sockjs;
                    // data.ws.stomp = ws.stomp;
                    // that.initSocket(soltkey);
                    // appLocalStorage.setLocal(appConst.search_dataImport_solt_key, soltkey);

                    data.projectDS = searchbar.getProjectDS();
                    data.importFiles = [];
                    components.div_spc_import_upload_files.empty();
                    var projectId = searchbar.getCurrentChoiceProjectId();
                    wizard.wizard('selectedItem', {
                        step: 1
                    });
                    components.slt_spc_import_project.select2("val", searchbar.getCurrentChoiceProjectId());
                    that.cleanImportDialogForm();
                    that.cleanImportDialogProcess();
                });

                components.dlg_spc_import.on('hide.bs.modal', function (e) {
                    that.cleanSocket();
                    if (components.slt_spc_import_project.select2('val') == searchbar.getCurrentChoiceProjectId()) {
                        searchbar.reloadStation();
                        searchbar.doSearch();
                    }
                });

                components.ckb_spc_import_enableBu5.on('click', function () {
                    var checked = $(this).is(':checked');
                    components.fle_spc_import_bu5Name.parent('.form-group').removeClass('has-error');
                    if (checked) {
                        components.fle_spc_import_bu5Name.prop('disabled', false);
                    } else {
                        components.fle_spc_import_bu5Name.prop('disabled', true);
                    }
                });
                components.btn_spc_import_submit.on('click', function (e) {
                    // var filePath = components.fle_spc_import_file.val();
                    if (data.importFiles.length == 0) {
                        components.alt_grr_import_msgbar.removeClass("alert-warning", "alert-danger").addClass("alert-warning").html($.i18n.prop('DATAIMPORT_ERR_MSG')).fadeIn(200);
                        return false;
                    }

                    var isCsv = true;
                    $.each(data.importFiles, function (i, obj) {
                        var fileTypes = ["csv"];
                        var fileType = obj.name.substring(obj.name.lastIndexOf('.') + 1);
                        if ($.inArray(fileType.toLocaleLowerCase(), fileTypes) == -1) {
                            components.alt_grr_import_msgbar.removeClass("alert-warning", "alert-danger").addClass("alert-warning").html($.i18n.prop('DATAIMPORT_ERR_MSG')).fadeIn(200);
                            isCsv = false;
                            return false;
                        }
                    });
                    if (isCsv == false) {
                        return false;
                    }

                    if (components.slt_spc_import_project.select2("val") == "") {
                        components.alt_grr_import_msgbar.removeClass("alert-warning", "alert-danger").addClass("alert-warning").html($.i18n.prop('DATAIMPORT_ERR_MSG')).fadeIn(200);
                        return false;
                    }

                    function timedCount(c) {
                        var time = dateUtils.second_to_date(c);
                        components.spn_spc_import_time.html(time);

                        var timeout = setTimeout(function () {
                            timedCount(c + 1);
                        }, 1000);
                        var obj = {timeout: timeout};
                        appLocalStorage.setLocal(data.search_timeout_key_spc, JSON.stringify(obj));
                    }

                    if (components.ckb_spc_import_enableBu5.is(":checked")) {
                        if (components.fle_spc_import_bu5Name.val() == "") {
                            components.fle_spc_import_bu5Name.parent('.form-group').addClass('has-error');
                            return false;
                        }
                    }
                    that.checkImportFile(function (d) {
                        if (d == true) {
                            components.alt_grr_import_msgbar.removeClass("alert-warning", "alert-danger").addClass("alert-danger").html("The file is already exists in the server.").fadeIn(200);
                            // msgBox.errorBox('EXCEPTION_GLOBAL_OBJECT_ALREADY_EXISTS', getFileNameFromPath(filePath));
                        } else {
                            var fileForm = $('#frm_spc_import');

                            fileForm.attr("action", 'data/import');
                            // fileForm.append("<input type='hidden' name='soltkey' value='"+data.soltkey+"'/>");
                            fileForm.submit();

                            wizard.wizard('selectedItem', {
                                step: 3
                            });

                            components.btn_spc_import_submit.hide();
                            components.btn_spc_import_gobackTo1.show();
                            that.cleanImportDialogProcess();
                            timedCount(0);
                        }
                    });

                });

                components.btn_spc_import_gobackTo1.on('click', function (e) {
                    // wizard.wizard('previous');
                    wizard.wizard('selectedItem', {
                        step: 1
                    });

                    that.cleanSocket();
                    that.initSocket();
                    $(this).hide();
                    that.cleanImportDialogProcess();
                    components.btn_spc_import_submit.show();
                });

                components.fle_spc_import_file.on("change", function (e) {
                    // components.div_spc_import_upload_files.empty();
                    components.alt_grr_import_msgbar.hide();
                    var files = e.target.files;
                    data.importFiles = [];

                    $.each(files, function (i, obj) {
                        data.importFiles.push(files[i]);
                    });

                    function drawFileList(fs) {
                        components.div_spc_import_upload_files.empty();
                        for (var i = 0; i < fs.length; i++) {
                            var fileName = fs[i].name;
                            var fileSize = mathUtils.round(fs[i].size / (1000 * 1000), 2) + "M";
                            components.div_spc_import_upload_files.append("<div class='txt-color-blue'>" + fileName + " : " + fileSize + "</div>");
                        }
                        // components.div_spc_import_upload_files.find('a').unbind('click').on('click', function (e) {
                        //     var code = Number($(this).attr('data-code'));
                        //     // fs.splice(code, 1);
                        //     var arrFile = [];
                        //     $.each(fs, function (i, obj) {
                        //         if (i != code) {
                        //             arrFile.push(fs[i]);
                        //         } else {
                        //             function errorHandler(){}
                        //             window.requestFileSystem(window.TEMPORARY, 1024*1024, function(fs) {
                        //                 fs.root.getFile(obj.name, {create: false}, function(fileEntry) {
                        //
                        //                     fileEntry.remove(function() {
                        //                         console.log('File removed.');
                        //                     }, errorHandler);
                        //
                        //                 }, errorHandler);
                        //             }, errorHandler);
                        //         }
                        //     });
                        //
                        //     data.importFiles = arrFile;
                        //     console.log(data.importFiles);
                        //     drawFileList(data.importFiles);
                        // });
                    }

                    drawFileList(data.importFiles);
                });
            },
            cleanImportDialogProcess: function () {
                components.spn_spc_import_processbar.removeClass("progress-bar-danger").removeClass("progress-bar-success").css('width', '0%').attr("aria-valuenow", 0);
                components.spn_spc_import_logArea.empty();
                components.spn_spc_import_status.empty();
                $('#spn_spc_import_operator').html($.i18n.prop('DATAIMPORT_ON_OPERATING', 0));
            },
            cleanImportDialogForm: function () {
                components.fle_spc_import_file.val("");
                components.btn_spc_import_submit.show();
                components.btn_spc_import_gobackTo1.hide();
                components.alt_grr_import_msgbar.hide();
            },
            checkImportFile: function (callback) {
                var path = components.fle_spc_import_file.val();
                var fileNames = [];
                $.each(data.importFiles, function (i, obj) {
                    fileNames.push(obj.name);
                });
                var param = {
                    search_originalName: JSON.stringify(fileNames),
                    search_projectId: components.slt_spc_import_project.select2("val")
                };
                testDataM.checkImportFile(param, function (d) {
                    if ($.isFunction(callback)) {
                        callback(d);
                    }
                });
            },
            initSocket: function () {
                var soltkey = Math.floor(Math.random(10) * 1000000);
                components.txt_spc_import_soltkey.val(soltkey);
                var ws = socketBiz.initImport(soltkey, that.socketCallback);
                data.ws.sockjs = ws.sockjs;
                data.ws.stomp = ws.stomp;
            },
            cleanSocket: function () {
                if (data.ws.stomp != null) {
                    data.ws.stomp.disconnect(function () {
                        data.ws.sockjs = null;
                        data.ws.stomp = null;
                        var queryParameter = appLocalStorage.getLocal(data.search_timeout_key_spc);
                        if (queryParameter != null) {
                            queryParameter = JSON.parse(queryParameter);
                            var timeout = queryParameter.timeout;
                            clearTimeout(timeout);
                        }
                    });
                }
            },
            socketCallback: function (pdata) {
                if (pdata.target == "SPC") {
                    var userId = global.getUserId();
                    socketBiz.receivedProcess(pdata, {
                        processbar: $("#spn_spc_import_processbar"),
                        pstatus: $('#spn_spc_import_status'),
                        poperator: $('#spn_spc_import_operator'),
                        plog: $('#spn_spc_import_logArea'),
                        psubmit: $('#btn_spc_import_submit'),
                        ptimeoutkey: appConst.searchKey.search_dataImport_timeout_key + userId
                    });
                }
            },

            //Global methods.
            activeAllElementsDependOnItem: function () {
                components.btn_refreshChart.attr('disabled', false);
                components.a_export_current.prop('disabled', false);
                components.btn_ispc_r_line_draw.prop('disabled', false);
                components.btn_ispc_mr_line_draw.prop('disabled', false);
                components.a_export_current.parent("li").removeClass('disabled');

                components.div_filterSearchBar.show();
                components.btn_refreshCache.attr('disabled', false);
            },
            disableAllElementsDependOnItem: function () {
                components.btn_refreshChart.attr('disabled', 'disabled');
                components.a_export_current.prop('disabled', true);
                components.btn_ispc_r_line_draw.prop('disabled', true);
                components.btn_ispc_mr_line_draw.prop('disabled', true);
                components.a_export_current.parent("li").addClass('disabled');
                components.div_filterSearchBar.hide();
                components.btn_refreshCache.attr('disabled', 'disabled');
            },
            activeExportBtn: function () {
                components.drp_export.prop('disabled', false);
            },
            disableExportBtn: function () {
                components.drp_export.prop('disabled', true);
            },

            lineRDrawEvent: function () {
                components.btn_ispc_r_line_draw.click(function () {
                    data.defineRLine = {};
                    data.defineRLine.line1Name = components.txt_ispc_r_line1_name.val();
                    data.defineRLine.line2Name = components.txt_ispc_r_line2_name.val();
                    data.defineRLine.line1Value = parseFloat(components.txt_ispc_r_line1_value.val());
                    data.defineRLine.line2Value = parseFloat(components.txt_ispc_r_line2_value.val());
                    that.loadChart();
                });

                components.btn_ispc_mr_line_draw.click(function () {
                    data.defineMRLine = {};
                    data.defineMRLine.line1Name = components.txt_ispc_mr_line1_name.val();
                    data.defineMRLine.line2Name = components.txt_ispc_mr_line2_name.val();
                    data.defineMRLine.line1Value = parseFloat(components.txt_ispc_mr_line1_value.val());
                    data.defineMRLine.line2Value = parseFloat(components.txt_ispc_mr_line2_value.val());
                    that.loadChart();
                });
            }
        }
    }
);